home *** CD-ROM | disk | FTP | other *** search
/ Aminet 34 / Aminet 34 (2000)(Schatztruhe)[!][Dec 1999].iso / Aminet / dev / basic / hookfunc.lha / hookfunc.bb2 next >
Encoding:
Text File  |  1999-10-20  |  8.9 KB  |  170 lines

  1. ; Description:  How to use hooks in Blitz. This one is an example for the ASL
  2. ;               screenmode requester and it works. Working parts by Paul "Mildred"
  3. ;               West.
  4. ;               You need amigalibsii.res resident.
  5. ;
  6. ;               Note that some things aren't explained fully (i.e. the tags
  7. ;               for the screenmode requester). You should look at the Autodocs
  8. ;               for these.
  9. ;
  10. ; Type:         SYSTEM
  11. ;
  12. ; Author:       David McMinn (dmcminn@house-of-mojo.freeserve.co.uk)
  13. ;
  14. ; Requires:     amigalibs.res
  15. ;
  16. ; History:
  17. ;   20 Oct 1999 Removed the pointless LEA from the hook (I'm sure it used to crash when I used JSR 6(a3)???)
  18. ;               Global variable base is now stored in some reserved memory, not the h_UserData field
  19. ;
  20. ;   ?? ??? ???? Written. Thanks to Paul West who got it working (Runerrsoff/on and jump to label+6)
  21. ;
  22.  
  23. MOVE.l  a5,globalbase   ; Store a copy of Blitz's global variable base pointer
  24.                         ; This should always be done somewhere before using the
  25.                         ; hooks, and only needs to be done once
  26.  
  27. ; These defines should be in amigalibsii.res, but they appear not to be
  28. #DTAG_DISP=$80000000
  29. #DTAG_DIMS=$80001000
  30. #DTAG_MNTR=$80002000
  31. #DTAG_NAME=$80003000
  32.  
  33. ; The initial values for the width and height when opening the screenmode
  34. ; requester (silly really, as we won't see them - see later in code)
  35. PrefDisplayWidth.w=320
  36. PrefDisplayHeight.w=240
  37.  
  38.  
  39. ; Define a hook, and set it
  40. DEFTYPE.Hook myhook             ; The hook for ASL tag as &myhook
  41. myhook\h_Entry=?hook            ; Set address of hook stub which sorts out registers and calls Blitz function
  42.                                 ; the hook stub in this code can be used as an all purpose hook
  43.                                 ; as long as you set the address of the function in the hook h_SubEntry
  44.                                 ; field and you set up this function so that it returns a long, and takes
  45.                                 ; three long parameters (standard for a hook function). The three
  46.                                 ; parameters will be as specified in the Autodocs for the hook
  47.                                 ; callback you are trying to use except the parameters will arrive
  48.                                 ; as parameter 1 instead of a0, parameter 2 instead of a1 and parameter 3
  49.                                 ; instead of a2.
  50. myhook\h_SubEntry = ?hook_jump  ; Set address of Blitz function that you want to use as hook callback
  51.                                 ; function
  52.                                 ; NB That you must have a label directly before the function
  53.  
  54.  
  55. ; Set up some tags for the ASL screenmode requester
  56. Dim SMRtags.TagItem(18)
  57. SMRtags(0)\ti_Tag=#ASLSM_InitialLeftEdge,160                    ; Initial left edge of requester
  58. SMRtags(1)\ti_Tag=#ASLSM_InitialTopEdge,0                       ; Initial top edge of requester
  59. SMRtags(2)\ti_Tag=#ASLSM_InitialWidth,300                       ; Initial width of requester
  60. SMRtags(3)\ti_Tag=#ASLSM_InitialHeight,600                      ; Initial height of requester
  61. SMRtags(4)\ti_Tag=#ASLSM_InitialDisplayID,$21000                ; Initial screenmode (if present, PAL:Lowres)
  62. SMRtags(5)\ti_Tag=#ASLSM_InitialDisplayDepth,8                  ; Initial depth of screen (in bitplanes/bits per pixel)
  63. SMRtags(6)\ti_Tag=#ASLSM_InitialDisplayWidth,PrefDisplayWidth   ; Initial width of desired screen
  64. SMRtags(7)\ti_Tag=#ASLSM_InitialDisplayHeight,PrefDisplayHeight ; Initial height of desired screen
  65. SMRtags(8)\ti_Tag=#ASLSM_InitialOverscanType,2                  ; Initial overscan type in cycle gadget (2 = #OSCAN_STANDARD)
  66. SMRtags(9)\ti_Tag=#ASLSM_InitialInfoOpened,1                    ; Set information box to open
  67. SMRtags(10)\ti_Tag=#ASLSM_InitialInfoLeftEdge,350               ; Initial left edge of info box
  68. SMRtags(11)\ti_Tag=#ASLSM_InitialInfoTopEdge,50                 ; Initial top edge of info box
  69. SMRtags(12)\ti_Tag=#ASLSM_DoDepth,0                             ; Don't show depth requester to user
  70. SMRtags(13)\ti_Tag=#ASLSM_DoOverscanType,1                      ; Show overscan cycle gadget to user
  71. SMRtags(14)\ti_Tag=#ASLSM_DoWidth,1                             ; Show width gadget to user
  72. SMRtags(15)\ti_Tag=#ASLSM_DoHeight,1                            ; Show height gadget to user
  73. SMRtags(16)\ti_Tag=#ASLSM_FilterFunc,&myhook                    ; Set hook for this function
  74. SMRtags(17)\ti_Tag=#TAG_END                                     ; End of tag list
  75.  
  76. ; Initialise and allocate a requester for the screenmode
  77. *sreq.ScreenModeRequester=0
  78. *sreq=AllocAslRequest_(#ASL_ScreenModeRequest,&SMRtags(0)\ti_Tag)
  79.  
  80. ; Display the requester
  81. ok.b=AslRequest_(*sreq,&SMRtags(0)\ti_Tag)
  82.  
  83. ; If the return value was not 0 (therefore a success)
  84. If ok<>0
  85.     ; Display the returned values in the structure allocated earlier
  86.     ; and wait for 3 seconds
  87.     NPrint *sreq\sm_DisplayID
  88.     NPrint *sreq\sm_DisplayWidth
  89.     NPrint *sreq\sm_DisplayHeight
  90.     Delay_ 150
  91. EndIf
  92. If (*sreq) Then FreeAslRequest_(*sreq)  ; If the screenmode allocation succeeded, then free theallocated memory
  93.  
  94.  
  95. ;*************************************************************************
  96. ; This is the Function that the hook will call.  Put the label before
  97. ; the Statement/Function you want To jump To. Note that you need to put
  98. ; Runnerrsoff and Runerrson around the statement or function.
  99. ;
  100. ; In this implementation, the ASL screenmode requester uses a hook to decide
  101. ; which screenmodes to display in the selection list. This function returns
  102. ; true for ASL to display the screenmode and false to not display the screenmode.
  103. ; The hook (and therefore this function) are called for every screenmode that
  104. ; ASL screenmode requester finds.
  105. Runerrsoff
  106. hook_jump:
  107. Function.l hook{*dahook.Hook, modeID.l, *smr.ScreenModeRequester}
  108.     DEFTYPE.DisplayInfo   DisInfoBuf ; Buffer to receive information about mode display
  109.     DEFTYPE.DimensionInfo DimInfoBuf ; Buffer to receive information about mode dimensions
  110.     DEFTYPE.MonitorInfo   MonInfoBuf ; Buffer to receive information about monitor (driver)
  111.     DEFTYPE.NameInfo      NamInfoBuf ; Buffer to receive information about mode name
  112.  
  113.     ; Gets a handle to a record of display information for the screenmode in question
  114.     IDhandle.l=FindDisplayInfo_(modeID)
  115.     ; Fill in the various buffers about this screenmode, using the newly
  116.     ; gotten handle
  117.     GetDisplayInfoData_ IDhandle,&DisInfoBuf,SizeOf.DisplayInfo,#DTAG_DISP,0
  118.     GetDisplayInfoData_ IDhandle,&DimInfoBuf,SizeOf.DimensionInfo,#DTAG_DIMS,0
  119.     GetDisplayInfoData_ IDhandle,&MonInfoBuf,SizeOf.MonitorInfo,#DTAG_MNTR,0
  120.     GetDisplayInfoData_ IDhandle,&NamInfoBuf,SizeOf.NameInfo,#DTAG_NAME,0
  121.  
  122.     ; Do tests. True=Mode is valid, False=mode is invalid. In these test, any mode
  123.     ; with a maximum horizontal width of less than 400 is rejected (i.e. PAL and
  124.     ; NTSC Lowres modes)
  125.     If DimInfoBuf\Nominal\MaxX < 400
  126.         Function Return False
  127.     Else
  128.         Function Return True
  129.     End If
  130. End Function
  131. Runerrson
  132. ;*************************************************************************
  133.  
  134.  
  135. ;*************************************************************************
  136. Goto HookSkip                       ; This is done so that hook code does not get
  137.                                     ; executed out of place
  138.  
  139. ; Code for calling the higher level hook functions. This piece of code is used
  140. ; for all hooks. Basically it puts whats in A0 (usually the *hook structure) into
  141. ; D0, A1 into D1 and A2 into D2. What this means is that within your high level
  142. ; function, you should have three parameters. These parameters must match up with
  143. ; what the Autodocs say will be passed in the address registers (given that they
  144. ; are put into the data registers). Remember that in Blitz, the parameters
  145. ; are in order of data register D0 first parameter, and so on.
  146. ; This hook will also return a value in D0, which is the value returned by the
  147. ; high level function. Some hook applications may need this, others may not,
  148. ; but I think it is pretty standard to return a value, even if it is a dummy
  149. ; value.
  150. hook:   MOVEM.l d1-d7/a0-a6,-(a7)   ; Save registers to stack (NOT D0!!!)
  151.  
  152.         MOVE.l a0,d0                ; These three moves put the hook parameters
  153.         MOVE.l a1,d1                ; (which are in A0-A2) into the data registers,
  154.         MOVE.l a2,d2                ; so that the Blitz function can access them
  155.  
  156.         MOVEA.l globalbase(pc),a5   ; Restore the global variable base
  157.         MOVEA.l 12(a0),a3           ; Get the address pointed to by the h_SubEntry field of the Hook structure
  158.         JSR     6(a3)               ; Get address of Blitz function and jump to it!
  159.  
  160.         ; The value is returned in d0 from the function. As this is where
  161.         ; we want it, nothing is done, and the hook returns.
  162.         MOVEM.l (a7)+,d1-d7/a0-a6   ; Restore registers from stack (NOT D0, we want to keep the return value)
  163.         RTS
  164.  
  165. globalbase: Ds.l  1                 ; Reserve 1 longword for storing Blitz's global variable base pointer
  166.  
  167. HookSkip
  168. End
  169.  
  170.